var GameController = require("GameController");
var Ini = require("Initiate");

cc.Class({
    extends: cc.Component,

    properties: {
        GM: {
            default: null,
            type: GameController
        },
        Arrow: {
            default: null,
            type: cc.Node
        },
        Initiate:{
            default: null,
            type:Ini
        },
        Boundary: {
            default: null,
            type: cc.Node
        },
        Grid: null,
        Option: null,
        Color: 0,
        RingAttachAllow: false,
        ShootSpeed: cc.v2,
        ShootAllowd: true,
        IfAttachedRight: false,
        AttachedRightType: null,
        AttachedWrongType: null,
        WallCount: 0
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    // TODO  碰撞产生消除行为
    ClearAct: function (MapX, MapY) {
        var CellArray = new Array();
        CellArray.push(this.Grid.MapGrid[MapX][MapY]);
        this.SameFind(MapX, MapY, CellArray);
        if (CellArray.length > 0)
            CellArray.forEach(element => {
                element.getComponent("CellBase").Clear();
            })
    },
    // 变色
    ColorChanger: function () {
        this.Color++;
        if (this.Color > this.Option.Color.length / 2 - 1) {
            this.Color = 0;
        }
        this.node.color = this.Option.Color[this.Color + this.Option.Color.length / 2];
        this.Boundary.getComponent("Boundary").ChangeColorNext(this.Color);
    },
    // 找到邻居中相同的细胞
    SameFind: function (MapX, MapY, CellArray) {
        this.Grid.MapGrid[MapX][MapY].getComponent("CellBase").AdjCells.forEach(element => {
            if (!CellArray.includes(element))
                if (element.getComponent("CellBase").type ==
                    this.Grid.MapGrid[MapX][MapY].getComponent("CellBase").type) {
                    CellArray.push(element);
                    this.SameFind(element.getComponent("CellBase").MapX, element.getComponent("CellBase").MapY, CellArray);
                }
        });
    },


    // 撞到细胞团的反弹
    GridBounce: function (other) {
        var position = cc.v2(this.node.x - other.x, this.node.y - other.y);
        var positionLong = Math.sqrt(position.x * position.x + position.y * position.y);
        var antiSpeed = cc.v2(-this.ShootSpeed.x, -this.ShootSpeed.y);
        var antiSpeedLong = Math.sqrt(antiSpeed.x * antiSpeed.x + antiSpeed.y * antiSpeed.y);
        var AP = cc.v2(position.x - antiSpeed.x, position.y - antiSpeed.y);
        var APLong = Math.sqrt(AP.x * AP.x + AP.y * AP.y);
        var OutShootSpeed = cc.v2((position.x * (antiSpeedLong * antiSpeedLong + positionLong * positionLong - APLong * APLong) / (positionLong * positionLong)) - antiSpeed.x,
            (position.y * (antiSpeedLong * antiSpeedLong + positionLong * positionLong - APLong * APLong) / (positionLong * positionLong)) - antiSpeed.y);
        this.ShootSpeed = OutShootSpeed;
        //console.log(this.node.position + this.ShootSpeed + OutShootSpeed);
    },
    // TODO 撞到墙壁反弹并变色
    BoundaryBounce: function (wallTag) {
        if (wallTag == 0) {
            this.ShootSpeed = cc.v2(this.ShootSpeed.x, Math.sign(this.node.y) * -1 * Math.abs(this.ShootSpeed.y));
        }
        else if (wallTag == 1) {
            this.ShootSpeed = cc.v2(Math.sign(this.node.x) * -1 * Math.abs(this.ShootSpeed.x), this.ShootSpeed.y);
        }
        console.log("Wall Attach & Change Color!");
        this.ColorChanger();
    },
    // TODO 停留到环上及行为
    RingAttach: function () {
        console.log("Ring Attach!");
        this.WallCount = 0;
        var attachPos = this.node.position;
        var attachLong = Math.sqrt(attachPos.x * attachPos.x + attachPos.y * attachPos.y);
        var Speed = Math.sqrt(this.ShootSpeed.x * this.ShootSpeed.x + this.ShootSpeed.y * this.ShootSpeed.y);
        var MoveTime = (attachLong -830) / Speed * 0.016;
        var actionBy = cc.moveTo(MoveTime, cc.v2(attachPos.x * 830 / attachLong, attachPos.y * 830 / attachLong));
        this.node.runAction(actionBy);
        this.ShootSpeed = cc.v2(0, 0);
        //this.node.position = cc.v2(attachPos.x * 830 / attachLong, attachPos.y * 830 / attachLong);
    },
    // 重置地图
    ResetMap:function () {
        this.Initiate.InitiateCells(this.Initiate);
    },
    //
    onCollisionEnter: function (other, self) {
        //console.log('on collision enter: ' + other.node.name);

        if (other.node.group == "Cell") {   // 撞到细胞
            console.log("Attach the Cell");
            this.GridBounce(other.node.position);
            if (other.node.getComponent("CellBase").MapX == this.Option.MapGridSize && other.node.getComponent("CellBase").MapY == this.Option.MapGridSize) {   // 中央细胞
                console.log("Attach the Center!");
                this.scheduleOnce(this.ResetMap, 2);
            }
            else {
                if (other.node.getComponent("CellBase").type == this.Color) {   // 同色
                    console.log("Clear cell of type" + this.Color);
                    var MapX = other.node.getComponent("CellBase").MapX;
                    var MapY = other.node.getComponent("CellBase").MapY;
                    this.ClearAct(MapX, MapY);
                    this.AttachedRightType = other.node.getComponent("CellBase").type;
                    this.IfAttachedRight = true;
                }
                else {  // 异色
                    console.log("Type ERROR!");
                    this.AttachedWrongType = other.node.getComponent("CellBase").type;
                }
            }
            //if(!this.RingAttachAllow)           
            this.RingAttachAllow = true;
            this.WallCount = 0;
        }
        else if (other.node.group == "Wall") {  // 墙
            this.BoundaryBounce(other.tag);
            this.WallCount ++;
            //第四次撞墙强制返回环
            if(this.WallCount > 2){
                this.RingAttach();
            }
        }
        else if (other.node.group == "Ring") {  // 环
            console.log("Ring Attach Allow: " + this.RingAttachAllow)
            if (this.RingAttachAllow) {
                this.RingAttach();
                this.RingAttachAllow = false;
                
            }
        }
    },
    onCollisionExit: function (other, self) {
        if (other.node.group == "Ring") {  
            //console.log("生命值结算!" + this.IfAttachedRight + " " + this.AttachedRightType + " " + this.AttachedWrongType);
            if(this.IfAttachedRight){
                this.IfAttachedRight = false;
                this.SameColorAct(this.AttachedRightType);  // 同色行为
                // 同色出环特效
            }
            else{
                this.WrongCell(this.AttachedWrongType); // 未撞到同色行为
                // 异色出环特效
            }
            this.AttachedRightType = null;  //记录置空
            this.AttachedWrongType = null;
        }
    },
    // TODO 相同颜色细胞效果
    SameColorAct: function (type) {
        console.log("撞到过同色细胞");
        switch (type) {
            case 0:
                this.GM.HPChanger(20);
                this.GM.AddScore(20);
                break;

            case 1:
                this.GM.HPChanger(10);
                this.GM.AddScore(10);
                break;

            case 2:
                this.GM.HPChanger(5);
                this.GM.AddScore(5);
                break;

            case 3:
                this.GM.HPChanger(7);
                this.GM.AddScore(7);
                break;

            case 4:
                this.GM.HPChanger(12);
                this.GM.AddScore(12);
                break;

            case 5:
                this.GM.HPChanger(15);
                this.GM.AddScore(15);
                break;
        }
    },
    // TODO 撞到错误细胞的效果
    WrongCell: function (type) {
        console.log("没有撞到过同色细胞");
        switch (type) {
            case 0:
                this.GM.HPChanger(-20);
                break;

            case 1:
                this.GM.HPChanger(-10);
                break;

            case 2:
                this.GM.HPChanger(-5);
                break;

            case 3:
                this.GM.HPChanger(-7);
                break;

            case 4:
                this.GM.HPChanger(-12);
                break;

            case 5:
                this.GM.HPChanger(-15);
                break;
        }
    },
    onLoad() {
        this.Grid = this.GM.Grid;
        this.Option = this.GM.Option;
        var manager = cc.director.getCollisionManager();
        manager.enabled = true;
        this.ShootSpeed = cc.v2(0, 0);
    },

    start() {
        this.Arrow.active = false;
    },

    update(dt) {
        this.dt = dt;
        //console.log(this.enabled);
        this.node.position = cc.v2(this.node.position.x + this.ShootSpeed.x, this.node.position.y + this.ShootSpeed.y);
        if (Math.abs(this.ShootSpeed.x) < 0.01 && Math.abs(this.ShootSpeed.y) < 0.01){
            this.ShootAllowd = true;
        }
        else this.ShootAllowd = false;
    },
});
